package com.decent.common.util;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.SecureUtil;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.UUID;

/**
 * 创建唯一订单号工具类
 *
 * @author wangyan
 */
public class CreateOrderNoUtil {

    /**
     * 获取订单号,前缀+yyMMddHHmmss+随机数,对外接口或者常用订单业务推荐使用。
     *
     * @param prefix 前缀
     * @param length 需要的长度
     * @return 订单号
     */
    public static String getExternalOrderId(String prefix, int length) {
        String timeStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmmss"));
        return prefix + timeStr + getOrderIdByUuid(length - prefix.length() - timeStr.length());
    }

    /**
     * 获取订单号,前缀+雪花随机数（19位）高并发下，推荐使用这个，具体api见
     * https://apidoc.gitee.com/dromara/hutool/
     *
     * @param prefix 前缀
     * @return 订单号
     */
    public static String getOrderIdBySnowflake(String prefix) {
        Snowflake snowflake = IdUtil.getSnowflake(1, 1);
        return prefix + snowflake.nextId();
    }

    /**
     * 创建短链接
     *
     * @param flowNo 订单号
     * @return 短连接
     */
    public static String createShortLink(String flowNo) {
        long timeStamp = System.currentTimeMillis();
        String md5 = SecureUtil.md5(flowNo + timeStamp).toUpperCase();
        return md5.substring(0, 12);
    }

    /**
     * 生成订单号，前缀+32位随机数
     *
     * @param prefix 前缀
     * @return 订单号
     */
    public static String buildOrderNumber(String prefix) {
        StringBuilder stringBuilder = new StringBuilder(32);
        String timestamp = String.valueOf(System.currentTimeMillis());
        stringBuilder.append(prefix)
                .append(getOrderIdByUuid(32 - prefix.length() - timestamp.length()))
                .append(timestamp);
        return stringBuilder.toString();
    }

    /**
     * 根据UUID生成订单号
     *
     * @return 订单号
     */
    public static String getOrderIdByUuid(int length) {
        String nanosecond = (System.nanoTime() + "").substring(7, 10);
        int hashCode = UUID.randomUUID().toString().hashCode();
        if (Integer.MIN_VALUE == hashCode) {
            hashCode = Integer.MAX_VALUE;
        } else if (hashCode < 0) {
            hashCode = -hashCode;
        }
        // 0 代表前面补充0，6 代表长度为6，d 代表参数为正数型
        return nanosecond + String.format("%0" + (length - 3) + "d", hashCode).substring(0, length - 3);
    }
}
